<!doctype html>

<html lang="zh-CN">

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  <link rel="shortcut icon" href="/favicon.ico">
  <title>论坛</title>
  <!-- 导入CSS -->
  <link href="./dist/css/tabler.min.css?1674944402" rel="stylesheet" />
  <link rel="stylesheet" href="./dist/css/jquery.toast.css">
  <link rel="stylesheet" href="./dist/editor.md/css/editormd.min.css">
  <link href="./dist/css/styles.css" rel="stylesheet" />
  <!-- 添加动画库 -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
  <!-- 自定义样式 -->
  <style>
    /* 全局过渡动画 */
    * {
      transition: all 0.3s ease-in-out;
    }
    
    /* 导航栏优化 */
    .navbar {
      backdrop-filter: blur(10px);
      -webkit-backdrop-filter: blur(10px);
      background-color: rgba(255, 255, 255, 0.8);
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
    }
    
    /* 铃铛摇晃动画 */
    @keyframes bellShake {
      0% { transform: rotate(0); }
      15% { transform: rotate(15deg); }
      30% { transform: rotate(-15deg); }
      45% { transform: rotate(10deg); }
      60% { transform: rotate(-10deg); }
      75% { transform: rotate(5deg); }
      85% { transform: rotate(-5deg); }
      92% { transform: rotate(3deg); }
      100% { transform: rotate(0); }
    }

    .nav-link:hover .icon-tabler-bell {
      animation: bellShake 0.8s ease-in-out;
      transform-origin: top center;
    }

    /* 消息通知徽章弹出动画 */
    @keyframes badgePop {
      0% { transform: scale(0.5); }
      50% { transform: scale(1.2); }
      100% { transform: scale(1); }
    }

    .new-message {
      animation: badgePop 0.5s ease-out;
    }

    /* 搜索框动效增强 */
    .input-icon {
      transition: all 0.3s ease;
    }

    .input-icon:hover {
      transform: translateY(-2px);
    }

    .input-icon .form-control:focus {
      box-shadow: 0 0 0 0.25rem rgba(32, 107, 196, 0.1);
      transform: translateY(-1px);
    }

    /* 下拉菜单动画 */
    .dropdown-menu {
      transform-origin: top;
      animation: dropdownFade 0.2s ease-out;
    }

    @keyframes dropdownFade {
      from {
        opacity: 0;
        transform: scaleY(0.9);
      }
      to {
        opacity: 1;
        transform: scaleY(1);
      }
    }

    /* 站内信列表项悬浮效果 */
    .list-group-item {
      transition: all 0.3s ease;
    }

    .list-group-item:hover {
      transform: translateX(5px);
      background-color: rgba(32, 107, 196, 0.05);
    }

    /* 滚动条美化 */
    ::-webkit-scrollbar {
      width: 8px;
      height: 8px;
    }

    ::-webkit-scrollbar-track {
      background: #f1f1f1;
      border-radius: 4px;
    }

    ::-webkit-scrollbar-thumb {
      background: #888;
      border-radius: 4px;
    }

    ::-webkit-scrollbar-thumb:hover {
      background: #555;
    }

    /* 返回顶部按钮样式优化 */
    .scroll-to-top {
      position: fixed;
      bottom: 20px;
      right: 20px;
      display: none;
      z-index: 1000;
      opacity: 0.8;
      border-radius: 50%;
      width: 40px;
      height: 40px;
      transition: all 0.3s ease;
    }

    .scroll-to-top:hover {
      opacity: 1;
      transform: translateY(-3px);
    }

    /* 主题切换按钮动效 */
    .nav-link[title*="切换"] {
      transition: transform 0.3s ease;
    }

    .nav-link[title*="切换"]:hover {
      transform: rotate(30deg);
    }

    /* 站内信未读状态动画 */
    .status-dot-animated {
      animation: pulse 2s infinite;
    }

    @keyframes pulse {
      0% { transform: scale(1); opacity: 1; }
      50% { transform: scale(1.2); opacity: 0.7; }
      100% { transform: scale(1); opacity: 1; }
    }
    
    /* 板块列表样式优化 */
    .nav-item {
      position: relative;
      margin: 0 5px;
      border-radius: 8px;
      transition: all 0.3s ease;
    }
    
    .nav-item:hover {
      background-color: rgba(32, 107, 196, 0.1);
    }
    
    .nav-item.active {
      background: linear-gradient(135deg, #206bc4 0%, #1b5bb7 100%);
      box-shadow: 0 4px 12px rgba(32, 107, 196, 0.2);
    }
    
    .nav-item.active .nav-link {
      color: white !important;
    }
    
    .nav-item.active .nav-link-icon {
      color: white !important;
    }
    
    .nav-link {
      padding: 10px 15px;
      display: flex;
      align-items: center;
      gap: 8px;
      color: #495057;
      font-weight: 500;
      border-radius: 8px;
      transition: all 0.3s ease;
    }
    
    .nav-link-icon {
      width: 24px;
      height: 24px;
      display: flex;
      align-items: center;
      justify-content: center;
      color: #206bc4;
      transition: all 0.3s ease;
    }
    
    .nav-link-title {
      font-size: 0.95rem;
      transition: all 0.3s ease;
    }
    
    .nav-item:hover .nav-link-title {
      transform: translateX(3px);
    }
    
    .nav-item:hover .nav-link-icon {
      transform: scale(1.1);
    }
    
    /* 导航栏容器样式 */
    .navbar-expand-md {
      background: rgba(255, 255, 255, 0.9);
      backdrop-filter: blur(10px);
      -webkit-backdrop-filter: blur(10px);
      border-bottom: 1px solid rgba(0, 0, 0, 0.05);
      padding: 10px 0;
    }
    
    .navbar-nav {
      display: flex;
      align-items: center;
      gap: 5px;
    }
    
    /* 用户头像动效 */
    .avatar {
      transition: transform 0.3s ease;
    }
    
    .avatar:hover {
      transform: scale(1.1);
    }
    
    /* 消息通知动画 */
    @keyframes notification-pulse {
      0% { transform: scale(1); }
      50% { transform: scale(1.1); }
      100% { transform: scale(1); }
    }
    
    .badge-notification {
      animation: notification-pulse 2s infinite;
    }
    
    /* 加载动画 */
    .page-loading {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(255, 255, 255, 0.8);
      display: flex;
      justify-content: center;
      align-items: center;
      z-index: 9999;
    }
    
    /* 卡片悬浮效果 */
    .card {
      transition: transform 0.3s ease, box-shadow 0.3s ease;
    }
    
    .card:hover {
      transform: translateY(-5px);
      box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
    }
    
    /* 按钮动效 */
    .btn {
      transition: transform 0.2s ease;
    }
    
    .btn:hover {
      transform: translateY(-2px);
    }
    
    /* 模态框动效 */
    .modal.show .modal-dialog {
      animation: slideIn 0.3s ease-out;
    }
    
    @keyframes slideIn {
      from {
        transform: translateY(-10%);
        opacity: 0;
      }
      to {
        transform: translateY(0);
        opacity: 1;
      }
    }

    /* 搜索框样式优化 */
    .search-container {
      position: relative;
      background: rgba(255, 255, 255, 0.9);
      border-radius: 8px;
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    }

    .search-container:focus-within {
      box-shadow: 0 4px 12px rgba(32, 107, 196, 0.2);
    }

    .search-board-select {
      border: none;
      background: transparent;
      border-right: 1px solid rgba(0, 0, 0, 0.1);
      border-radius: 8px 0 0 8px;
      padding: 8px 12px;
      font-size: 0.9rem;
      color: #495057;
    }

    .search-board-select:hover {
      background: rgba(32, 107, 196, 0.05);
    }

    .search-input-wrapper {
      position: relative;
      display: flex;
      align-items: center;
    }

    .search-input {
      border: none;
      background: transparent;
      padding: 8px 12px;
      font-size: 0.9rem;
      border-radius: 0 8px 8px 0;
    }

    .search-input:focus {
      box-shadow: none;
    }

    .search-icon {
      color: #206bc4;
    }

    .clear-icon {
      cursor: pointer;
      color: #adb5bd;
    }

    .clear-icon:hover {
      color: #206bc4;
    }

    /* 搜索结果样式优化 */
    .search-result-item {
      padding: 16px;
      border-bottom: 1px solid rgba(0, 0, 0, 0.05);
      transition: all 0.3s ease;
    }

    .search-result-item:hover {
      background: rgba(32, 107, 196, 0.05);
      transform: translateX(5px);
    }

    .search-result-title {
      font-size: 1.1rem;
      color: #206bc4;
      margin-bottom: 8px;
    }

    .search-result-meta {
      font-size: 0.85rem;
      color: #6c757d;
    }

    .search-result-highlight {
      background: rgba(32, 107, 196, 0.1);
      padding: 2px 4px;
      border-radius: 4px;
      color: #206bc4;
    }

    /* 网站标题样式 */
    .site-title-content {
      display: flex;
      align-items: center;
      text-decoration: none;
      transition: all 0.3s ease;
      gap: 8px;
    }

    .site-title-text {
      font-size: 1.4rem;
      font-weight: 600;
      color: #206bc4;
      position: relative;
      display: inline-block;
      white-space: nowrap;
    }

    /* 浮动图标样式 */
    .floating-icon {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 32px;
      height: 32px;
      background: rgba(32, 107, 196, 0.1);
      border-radius: 50%;
      padding: 4px;
      animation: float 3s ease-in-out infinite;
    }

    .floating-icon svg {
      width: 24px;
      height: 24px;
      color: #206bc4;
      transition: all 0.3s ease;
    }

    .site-title-content:hover .floating-icon svg {
      transform: rotate(15deg);
      color: #1b5bb7;
    }

    /* 浮动动画 */
    @keyframes float {
      0% {
        transform: translateY(0px);
      }
      50% {
        transform: translateY(-5px);
      }
      100% {
        transform: translateY(0px);
      }
    }

    /* 图标呼吸效果 */
    @keyframes breathe {
      0% {
        box-shadow: 0 0 0 0 rgba(32, 107, 196, 0.4);
      }
      70% {
        box-shadow: 0 0 0 10px rgba(32, 107, 196, 0);
      }
      100% {
        box-shadow: 0 0 0 0 rgba(32, 107, 196, 0);
      }
    }

    .floating-icon {
      animation: float 3s ease-in-out infinite, breathe 2s ease-in-out infinite;
    }

    .site-title-text::after {
      content: '';
      position: absolute;
      width: 100%;
      height: 2px;
      bottom: -2px;
      left: 0;
      background-color: #206bc4;
      transform: scaleX(0);
      transform-origin: right;
      transition: transform 0.3s ease;
    }

    .site-title-content:hover .site-title-text {
      color: #1b5bb7;
    }

    .site-title-content:hover .site-title-text::after {
      transform: scaleX(1);
      transform-origin: left;
    }

    /* AI对话按钮样式 */
    .ai-chat-btn {
      position: fixed;
      bottom: 80px;
      right: 20px;
      width: 60px;
      height: 60px;
      border-radius: 50%;
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      color: white;
      border: none;
      box-shadow: 0 4px 20px rgba(102, 126, 234, 0.4);
      transition: all 0.3s ease;
      z-index: 1000;
      display: flex;
      align-items: center;
      justify-content: center;
      cursor: pointer;
    }

    .ai-chat-btn:hover {
      transform: translateY(-3px) scale(1.05);
      box-shadow: 0 8px 25px rgba(102, 126, 234, 0.6);
      background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
    }

    .ai-chat-btn svg {
      width: 28px;
      height: 28px;
      animation: ai-pulse 2s infinite;
    }

    @keyframes ai-pulse {
      0% { transform: scale(1); }
      50% { transform: scale(1.1); }
      100% { transform: scale(1); }
    }

    /* AI对话框样式 */
    .ai-chat-modal .modal-dialog {
      max-width: 800px;
      height: 80vh;
    }

    .ai-chat-modal .modal-content {
      height: 100%;
      display: flex;
      flex-direction: column;
    }

    .ai-chat-header {
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      color: white;
      border-radius: 0.5rem 0.5rem 0 0;
      padding: 1rem;
    }

    .ai-chat-body {
      flex: 1;
      overflow-y: auto;
      padding: 1rem;
      background: #f8f9fa;
    }

    .ai-chat-footer {
      padding: 1rem;
      border-top: 1px solid #dee2e6;
      background: white;
    }

    .chat-message {
      margin-bottom: 1rem;
      display: flex;
      align-items: flex-start;
    }

    .chat-message.user {
      justify-content: flex-end;
    }

    .chat-message.ai {
      justify-content: flex-start;
    }

    .message-content {
      max-width: 70%;
      padding: 0.75rem 1rem;
      border-radius: 1rem;
      position: relative;
      word-wrap: break-word;
    }

    .chat-message.user .message-content {
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      color: white;
      border-bottom-right-radius: 0.25rem;
    }

    .chat-message.ai .message-content {
      background: white;
      color: #333;
      border: 1px solid #e9ecef;
      border-bottom-left-radius: 0.25rem;
    }

    .message-avatar {
      width: 32px;
      height: 32px;
      border-radius: 50%;
      margin: 0 0.5rem;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 0.8rem;
      font-weight: bold;
    }

    .chat-message.user .message-avatar {
      background: #206bc4;
      color: white;
      order: 2;
    }

    .chat-message.ai .message-avatar {
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      color: white;
    }

    .chat-input-group {
      display: flex;
      gap: 0.5rem;
    }

    .chat-input {
      flex: 1;
      border: 1px solid #dee2e6;
      border-radius: 1.5rem;
      padding: 0.75rem 1rem;
      resize: none;
      max-height: 100px;
    }

    .chat-send-btn {
      width: 50px;
      height: 50px;
      border-radius: 50%;
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      color: white;
      border: none;
      display: flex;
      align-items: center;
      justify-content: center;
      transition: all 0.3s ease;
    }

    .chat-send-btn:hover {
      transform: scale(1.05);
      box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
    }

    .chat-send-btn:disabled {
      opacity: 0.6;
      cursor: not-allowed;
    }

    .typing-indicator {
      display: flex;
      align-items: center;
      gap: 0.25rem;
      padding: 0.5rem;
    }

    .typing-dot {
      width: 8px;
      height: 8px;
      border-radius: 50%;
      background: #667eea;
      animation: typing 1.4s infinite;
    }

    .typing-dot:nth-child(2) {
      animation-delay: 0.2s;
    }

    .typing-dot:nth-child(3) {
      animation-delay: 0.4s;
    }

    @keyframes typing {
      0%, 60%, 100% {
        transform: translateY(0);
        opacity: 0.4;
      }
      30% {
        transform: translateY(-10px);
        opacity: 1;
      }
    }

    /* 新建对话按钮样式 */
    .new-chat-btn {
      border: 1px solid rgba(255, 255, 255, 0.3) !important;
      color: white !important;
      background: rgba(255, 255, 255, 0.1) !important;
      transition: all 0.3s ease;
      font-size: 0.875rem;
      padding: 0.375rem 0.75rem;
      border-radius: 0.375rem;
    }

    .new-chat-btn:hover {
      background: rgba(255, 255, 255, 0.2) !important;
      border-color: rgba(255, 255, 255, 0.5) !important;
      color: white !important;
      transform: translateY(-1px);
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
    }

    .new-chat-btn:active {
      transform: translateY(0);
      box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
    }

    .new-chat-btn svg {
      margin-right: 0.25rem;
    }
  </style>
  <!-- 设置字体 -->
  <!-- <style>
      @import url('https://rsms.me/inter/inter.css');
      :root {
      	--tblr-font-sans-serif: 'Inter Var', -apple-system, BlinkMacSystemFont, San Francisco, Segoe UI, Roboto, Helvetica Neue, sans-serif;
      }
      body {
      	font-feature-settings: "cv03", "cv04", "cv11";
      }
    </style> -->
</head>

<body>
  <!-- page 页面开始 -->
  <div class="page">
    <!-- 头部 导航 开始 -->
    <header class="navbar navbar-expand-md navbar-light d-print-none sticky-top">
      <div class="container-xl">
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar-menu"
          aria-controls="navbar-menu" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
        <!-- 导航左侧 logo 按钮 -->
        <div class="navbar-brand navbar-brand-autodark d-none-navbar-horizontal pe-0 pe-md-3">
          <a href="javascript:void(0);" class="site-title-content">
            <span class="floating-icon">
              <svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
                <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
                <path d="M12 3l8 4.5v9l-8 4.5l-8 -4.5v-9l8 -4.5" />
                <path d="M12 12l8 -4.5" />
                <path d="M12 12v9" />
                <path d="M12 12l-8 -4.5" />
                <path d="M16 5.25l-8 4.5" />
              </svg>
            </span>
            <span class="site-title-text">大学生技术交流平台</span>
          </a>
        </div>
        <!-- 导航右侧 -->
        <div class="navbar-nav flex-row order-md-last">
          <!-- 搜索框 -->
          <div class="nav-item d-none d-md-flex me-3">
            <div class="my-2 my-md-0 flex-grow-1 flex-md-grow-0 order-first order-md-last">
              <form id="searchForm" action="javascript:void(0);" method="get" autocomplete="off" novalidate>
                <div class="d-flex search-container">
                  <!-- 添加板块选择下拉框 -->
                  <select class="form-select me-2 search-board-select" id="searchBoardId">
                    <option value="">全部板块</option>
                    <!-- 板块选项会在buildTopBoard函数中动态添加 -->
                  </select>
                  <!-- 搜索框 -->
                  <div class="input-icon flex-grow-1 search-input-wrapper">
                    <span class="input-icon-addon search-icon">
                      <svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
                        stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
                        <path stroke="none" d="M0 0h24v24H0z" fill="none" />
                        <path d="M10 10m-7 0a7 7 0 1 0 14 0a7 7 0 1 0 -14 0" />
                        <path d="M21 21l-6 -6" />
                      </svg>
                    </span>
                    <input type="text" id="searchKeyword" class="form-control search-input" placeholder="输入关键字..."
                      aria-label="Search in website">
                    <span class="input-icon-addon clear-icon" style="display: none;">
                      <svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
                        stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
                        <path stroke="none" d="M0 0h24v24H0z" fill="none" />
                        <path d="M18 6l-12 12" />
                        <path d="M6 6l12 12" />
                      </svg>
                    </span>
                  </div>
                </div>
              </form>
            </div>
          </div>
          <!-- 主题样式日夜转换 -->
          <div class="d-none d-md-flex">
            <a href="?theme=dark" class="nav-link px-0 hide-theme-dark" title="切换至夜间模式" data-bs-toggle="tooltip"
              data-bs-placement="bottom">
              <svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
                stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
                <path stroke="none" d="M0 0h24v24H0z" fill="none" />
                <path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" />
              </svg>
            </a>
            <a href="?theme=light" class="nav-link px-0 hide-theme-light" title="切换至白天模式" data-bs-toggle="tooltip"
              data-bs-placement="bottom">
              <svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
                stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
                <path stroke="none" d="M0 0h24v24H0z" fill="none" />
                <path d="M12 12m-4 0a4 4 0 1 0 8 0a4 4 0 1 0 -8 0" />
                <path d="M3 12h1m8 -9v1m8 8h1m-9 8v1m-6.4 -15.4l.7 .7m12.1 -.7l-.7 .7m0 11.4l.7 .7m-12.1 -.7l-.7 .7" />
              </svg>
            </a>

            <!-- 小铃铛，站内信 -->
            <div class="nav-item dropdown d-none d-md-flex me-3">
              <a class="nav-link px-0 position-relative" data-bs-toggle="offcanvas" href="#index_message_offcanvasEnd" aria-controls="offcanvasEnd">
                <svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
                  <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
                  <path d="M10 5a2 2 0 0 1 4 0a7 7 0 0 1 4 6v3a4 4 0 0 0 2 3h-16a4 4 0 0 0 2 -3v-3a7 7 0 0 1 4 -6" />
                  <path d="M9 17v1a3 3 0 0 0 6 0v-1" />
                </svg>
                <span class="badge bg-red badge-pill badge-notification" id="index_nva_message_badge" style="display: none;" title="未读消息">0</span>
              </a>
            </div>
          </div>

          <!-- 用户信息 -->
          <div class="nav-item dropdown">
            <a href="#" class="nav-link d-flex lh-1 text-reset p-0" data-bs-toggle="dropdown"
              aria-label="Open user menu">
              <!-- 用户头像，也可以用img标签 -->
              <span id="index_nav_avatar" class="avatar avatar-sm"
                style="background-image: url(./image/avatar01.jpeg)"></span>
              <div class="d-none d-xl-block ps-2">
                <!-- 用户名 -->
                <div id="index_nav_nickname"></div>
                <!-- 副标题 -->
                <div id="index_nav_name_sub" class="mt-1 small text-muted"></div>
              </div>
            </a>
            <!-- 下拉菜单 -->
            <div class="dropdown-menu dropdown-menu-end dropdown-menu-arrow">
              <a href="javascript:void(0);" id="index_user_profile" class="dropdown-item">我的帖子</a>
              <a href="javascript:void(0);" id="index_user_settings" class="dropdown-item">个人中心</a>
              <!-- <a href="#" class="dropdown-item">状态</a> -->
              <!-- <a href="#" class="dropdown-item">生成二唯码</a> -->
              <div class="dropdown-divider"></div>
              <a id="index_user_logout" href="javascript:void(0);" class="dropdown-item"><span
                  class="text-red">退出</span></a>
            </div>
          </div>
        </div>
      </div>
    </header>

    <!-- 论坛版块导航 -->
    <header class="navbar-expand-md">
      <div class="collapse navbar-collapse" id="navbar-menu">
        <div class="navbar navbar-light">
          <div class="container-xl">
            <ul id="topBoardList" class="navbar-nav">
              <li class="nav-item active" id="nav_board_index">
                <!-- 首页 -->
                <a class="nav-link" href="javascript:void(0);">
                  <span
                    class="nav-link-icon d-md-none d-lg-inline-block"><!-- Download SVG icon from http://tabler-icons.io/i/star -->
                    <svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24"
                      stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
                      <path stroke="none" d="M0 0h24v24H0z" fill="none" />
                      <path
                        d="M12 17.75l-6.172 3.245l1.179 -6.873l-5 -4.867l6.9 -1l3.086 -6.253l3.086 6.253l6.9 1l-5 4.867l1.179 6.873z" />
                    </svg>
                  </span>
                  <span class="nav-link-title">
                    首页
                  </span>
                </a>
              </li>
              <!-- 其他版块动态生成 -->
            </ul>
          </div>
        </div>
      </div>
    </header>
    <!-- 头部 导航 结束 -->
    <!-- 正文 开始 -->
    <div class="page-wrapper" id="page-wrapper">
      <!-- 正文部分动态加载 -->
      <div id="bit-forum-content">

      </div>
      
      <!-- 站内信区域 开始 -->
      <div class="offcanvas offcanvas-end" tabindex="-1" id="index_message_offcanvasEnd" aria-labelledby="offcanvasEndLabel" style="width: 650px">
        <div class="offcanvas-header">
          <h2 class="offcanvas-title" id="offcanvasEndLabel">所有站内信</h2>
          <button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
        </div>
        <div class="offcanvas-body" id="index_div_message">
          <div class="list-group list-group-flush list-group-hoverable" id="index_div_message_list">
            <!-- 站内信列表开始 动态加载 -->
            
            <!-- 站内信列表结束 -->
          </div>
        </div>
      </div>
      <!-- 站内信区域 结束 -->
      <!-- 页脚 开始 -->
      <footer class="footer footer-transparent d-print-none align-self-center">
        <div class="container-xl">
          <div class="row text-center align-items-center">
            <div class="col-lg-auto ms-lg-auto">
              <ul class="list-inline list-inline-dots mb-0">
                <li class="list-inline-item">
                  Copyright &copy; 2025
                  <a href="#" class="link-secondary">论坛</a>
                  版权所有
                </li>
                <li class="list-inline-item">
                  <a href="https://gitee.com/yi-can-star" class="link-secondary">
                    GITEE
                  </a>
                </li>
              </ul>
            </div>
          </div>
        </div>
        <!-- 页脚 结束 -->
      </footer>
    </div>

    <!-- page 页面结束 -->
  </div>

  <!-- 发送站内信模态框 -->
  <div class="modal modal-blur fade" id="index_message_modal" tabindex="-1" role="dialog" aria-hidden="true">
    <div class="modal-dialog modal-lg" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title">发送站内信</h5>
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
        </div>
        
        <div class="modal-body">
          <div class="row">
            <div class="col-lg-12">
              <div>
                <input type="text" style="display: none;" id="index_message_receive_user_id">
                <label class="form-label" id="index_message_receive_user_name">发送给: </label>
                <textarea class="form-control" rows="5" id="index_message_receive_content"></textarea>
              </div>
            </div>
          </div>
        </div>
        <div class="modal-footer">
          <a href="javascript:void(0);" class="btn me-auto" data-bs-dismiss="modal" id="index_message_receive_cancel">
            取消
          </a>
          <a href="javascript:void(0);" class="btn btn-primary ms-auto" data-bs-dismiss="modal" id="btn_index_send_message">
            <!-- Download SVG icon from http://tabler-icons.io/i/plus -->
            <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-send" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
              <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
              <path d="M10 14l11 -11"></path>
              <path d="M21 3l-6.5 18a.55 .55 0 0 1 -1 0l-3.5 -7l-7 -3.5a.55 .55 0 0 1 0 -1l18 -6.5"></path>
           </svg>
            发送
          </a>
        </div>
      </div>
    </div>
  </div>

  <!-- 阅读和回复站内信模态框 -->
  <div class="modal modal-blur fade" id="index_message_reply_modal" tabindex="-1" role="dialog" aria-hidden="true">
    <div class="modal-dialog modal-lg" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title" id="index_message_detail_title">站内信详情</h5>
          <input type="text" style="display: none;" id="index_message_detail_id">
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
        </div>
        <div class="modal-body">
          <div class="row">
            <div class="col-lg-12">
              <div>
                <p id="index_message_detail_content"></p>
              </div>
            </div>
          </div>
        </div>
        <div class="modal-body" style="display: none;" id="index_message_reply_div">
          <div class="row">
            <div class="col-lg-12">
              <div>
                <input type="text" style="display: none;" id="index_message_reply_receive_user_id">
                <label class="form-label" id="index_message_reply_receive_user_name">回复给: </label>
                <textarea class="form-control" rows="5" id="index_message_reply_receive_content" placeholder="请输入回复内容"></textarea>
              </div>
            </div>
          </div>
        </div>
        <div class="modal-footer">
          <a href="javascript:void(0);" class="btn me-auto" data-bs-dismiss="modal" id="index_message_reply_cancel">
            取消
          </a>
          <a href="javascript:void(0);" class="btn btn-primary ms-auto" id="btn_index_message_reply">
            <!-- Download SVG icon from http://tabler-icons.io/i/plus -->
            <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-message" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
              <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
              <path d="M8 9h8"></path>
              <path d="M8 13h6"></path>
              <path d="M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3h12z"></path>
           </svg>
            回复
          </a>
          <a href="javascript:void(0);" class="btn btn-primary ms-auto" data-bs-dismiss="modal" id="btn_index_send_message_reply" style="display: none;">
            <!-- Download SVG icon from http://tabler-icons.io/i/plus -->
            <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-send" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
              <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
              <path d="M10 14l11 -11"></path>
              <path d="M21 3l-6.5 18a.55 .55 0 0 1 -1 0l-3.5 -7l-7 -3.5a.55 .55 0 0 1 0 -1l18 -6.5"></path>
           </svg>
            发送
          </a>
        </div>
      </div>
    </div>
  </div>

  <!-- 添加页面加载动画 -->
  <div class="page-loading" id="pageLoading">
    <div class="spinner-border text-primary" role="status">
      <span class="visually-hidden">Loading...</span>
    </div>
  </div>

  <!-- 添加返回顶部按钮 -->
  <button class="btn btn-primary btn-icon scroll-to-top" id="scrollToTop">
    <svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24">
      <path d="M12 4l8 8h-6v8h-4v-8H4z"/>
    </svg>
  </button>

  <!-- AI对话按钮 -->
  <button class="ai-chat-btn" id="aiChatBtn" data-bs-toggle="modal" data-bs-target="#aiChatModal">
    <svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
      <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
      <path d="M8 10h.01"></path>
      <path d="M12 10h.01"></path>
      <path d="M16 10h.01"></path>
    </svg>
  </button>

  <!-- AI对话模态框 -->
  <div class="modal modal-blur fade ai-chat-modal" id="aiChatModal" tabindex="-1" role="dialog" aria-hidden="true">
    <div class="modal-dialog modal-lg" role="document">
      <div class="modal-content">
        <div class="ai-chat-header">
          <h5 class="modal-title d-flex align-items-center">
            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="me-2">
              <circle cx="12" cy="12" r="5"></circle>
              <path d="M12 1v6m0 6v6"></path>
              <path d="m4.93 4.93 4.24 4.24m5.66 5.66 4.24 4.24"></path>
              <path d="m1 12 6 0m6 0 6 0"></path>
              <path d="m4.93 19.07 4.24-4.24m5.66-5.66 4.24-4.24"></path>
            </svg>
            AI智能助手
          </h5>
          <div class="d-flex align-items-center gap-2">
            <button type="button" class="btn btn-sm btn-outline-light new-chat-btn" id="newChatBtn" title="新建对话">
              <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <path d="M12 5v14"></path>
                <path d="M5 12h14"></path>
              </svg>
              新建对话
            </button>
            <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
          </div>
        </div>
        <div class="ai-chat-body" id="chatMessages">
          <div class="chat-message ai">
            <div class="message-avatar">AI</div>
            <div class="message-content">
              你好！我是论坛的AI智能助手，可以帮助你解答技术问题、提供学习建议或协助你更好地使用论坛功能。有什么我可以帮助你的吗？
            </div>
          </div>
        </div>
        <div class="ai-chat-footer">
          <div class="chat-input-group">
            <textarea class="form-control chat-input" id="chatInput" placeholder="输入你的问题..." rows="1"></textarea>
            <button class="chat-send-btn" id="chatSendBtn">
              <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <path d="M22 2 11 13"></path>
                <path d="m22 2-7 20-4-9-9-4z"></path>
              </svg>
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!-- 在body结束标签前添加脚本 -->
  <script>
    // 页面加载动画
    document.addEventListener('DOMContentLoaded', function() {
      const pageLoading = document.getElementById('pageLoading');
      if (pageLoading) {
        setTimeout(() => {
          pageLoading.style.opacity = '0';
          setTimeout(() => {
            pageLoading.style.display = 'none';
          }, 300);
        }, 500);
      }
      
      // 为导航项添加动画类
      const navItems = document.querySelectorAll('.nav-item');
      navItems.forEach((item, index) => {
        item.classList.add('animate__animated');
        item.style.animationDelay = `${index * 0.1}s`;
        item.addEventListener('mouseenter', () => {
          item.classList.add('animate__pulse');
        });
        item.addEventListener('animationend', () => {
          item.classList.remove('animate__pulse');
        });
      });
      
      // 搜索框焦点效果
      const searchInput = document.getElementById('searchKeyword');
      if (searchInput) {
        searchInput.addEventListener('focus', () => {
          searchInput.parentElement.style.transform = 'scale(1.02)';
        });
        searchInput.addEventListener('blur', () => {
          searchInput.parentElement.style.transform = 'scale(1)';
        });
      }
      
      // 消息通知动画
      const messageBadge = document.getElementById('index_nva_message_badge');
      if (messageBadge && messageBadge.style.display !== 'none') {
        messageBadge.classList.add('badge-notification');
      }
      
      // 模态框动画
      const modals = document.querySelectorAll('.modal');
      modals.forEach(modal => {
        modal.addEventListener('show.bs.modal', function() {
          this.querySelector('.modal-dialog').classList.add('animate__animated', 'animate__fadeInDown');
        });
        modal.addEventListener('hide.bs.modal', function() {
          this.querySelector('.modal-dialog').classList.add('animate__animated', 'animate__fadeOutUp');
        });
      });
      
      // 卡片出现动画
      const observerOptions = {
        threshold: 0.1
      };
      
      const observer = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
          if (entry.isIntersecting) {
            entry.target.classList.add('animate__animated', 'animate__fadeInUp');
            observer.unobserve(entry.target);
          }
        });
      }, observerOptions);
      
      // 监听所有卡片元素
      document.querySelectorAll('.card').forEach(card => {
        observer.observe(card);
      });
    });
  </script>
</body>
<!-- 导入JS -->
<script src="./dist/js/tabler.min.js"></script>
<script src="./dist/js/theme.min.js"></script>
<script src="./dist/js/jquery-3.6.3.min.js"></script>
<script src="./dist/js/jquery.toast.js"></script>
<script src="./js/common.js"></script>
<!-- 编辑器 -->
<script src="./dist/editor.md/editormd.min.js"></script>
<script src="./dist/editor.md/lib/marked.min.js"></script>
<script src="./dist/editor.md/lib/prettify.min.js"></script>
<script src="./dist/libs/tinymce/tinymce.min.js" defer></script>
<script>
  $(function () {
    //========================= 获取用户信息 =======================
    $.ajax({
        type: 'GET',
        url: '/user/info',
        success: function(response) {
            let user = response.data;
            if (response.code == 0) {
                if (user.avatarUrl == null) {
                  user.avatarUrl = avatarUrl;
                }
                $('#index_nav_avatar').css('background-image', 'url(' + user.avatarUrl + ')');
                $('#index_nav_nickname').html(user.nickname);
                
                // 构建用户身份和性别信息
                let subName = user.isAdmin == 1 ? '管理员' : '普通用户';
                let genderText = '';
                if (user.gender === 1) {
                    genderText = ' · 男';
                } else if (user.gender === 2) {
                    genderText = ' · 女';
                } else if (user.gender === 0) {
                    genderText = ' · 保密';
                }
                $('#index_nav_name_sub').html(subName + genderText);
            } else {
              // 提示信息
              $.toast({
                    heading: '警告',
                    text: response.message,
                    icon: 'warning'
                  });
            }
        }
    });

    // ========================= 获取版块信息 =======================
    // 成功后，调用buildTopBoard()方法，构建版块列表
    $.ajax({
      type: 'GET',
      url: '/board/topList',
      success: function(response) {
          if (response.code == 0) {
            // 构建板块列表
            buildTopBoard(response.data);
          } else {
            // 提示信息
            $.toast({
              heading: '警告',
              text: response.message,
              icon: 'warning'
            });
        }
      }
    });

    //========================= 构造首页版块=======================
    // 构造首页版块
    function buildTopBoard(data) {
      // 版块导航
      let navBoardListEl = $('#topBoardList');
      // 搜索框的板块选择
      let searchBoardSelect = $('#searchBoardId');
      
      // 遍历版块
      data.forEach(board => {
        // 构建版块
        let itemHtml = '<li class="nav-item">'
          + '<a class="nav-link" href="javascript:void(0);">'
          + '<span class="nav-link-icon">'
          + '<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-point-filled" width="24"'
          + 'height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"'
          + 'stroke-linecap="round" stroke-linejoin="round">'
          + '<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>'
          + '<path d="M12 7a5 5 0 1 1 -4.995 5.217l-.005 -.217l.005 -.217a5 5 0 0 1 4.995 -4.783z"'
          + 'stroke-width="0" fill="currentColor"></path>'
          + '</svg>'
          + '</span>'
          + '<span class="nav-link-title">'
          + board.name
          + '</span>'
          + '</a>'
          + '</li>';
        // 为版块绑定当前版块数据对象以便后续获取
        let boardItem = $(itemHtml);
        // 把版块信息绑定到当前导航单元
        boardItem.data('board', board);
        // 处理点击事件
        boardItem.click(function () {
          // 激活效果
          changeNavActive(boardItem);
        });
        // 加入版块导航
        navBoardListEl.append(boardItem);
        
        // 添加到搜索框的板块选择
        searchBoardSelect.append(`<option value="${board.id}">${board.name}</option>`);
      });
    }

    // ========================= 绑定导航栏中首页点击事件 =======================
    $('#nav_board_index').click(function () {
      // 激活效果
      changeNavActive($(this));
    });


    // ========================= 起始页而加载首页帖子列表 ========================= 
    buildArticleList();


    // ============================ 处理个设置心点击事件 ===========================
    $('#index_user_settings').click(function () {
      console.log('加载设置中心页面');
      removeNavActive();
      $('#bit-forum-content').load('settings.html');
    });

    // ============================ 处理个人中心点击事件 ===========================
    $('#index_user_profile').click(function () {
      console.log('加载个人中心页面');
      removeNavActive();
      // 清空要查看的用户Id，表示要查看的是自己
      profileUserId = undefined;
      // 加载个人帖子列表
      $('#bit-forum-content').load('profile.html');
    });

    // ============================ 处理退出登录点击事件 ===========================
    // 成功后，跳转到sign-in.html
    $('#index_user_logout').click(function () {
      $.ajax({
        type: 'GET',
        url: 'user/logout',
        complete: function() {
          location.assign('/sign-in.html');
        }
      });
    });

    // ============ 发送站内信 ==============
    $('#btn_index_send_message').click(function() {
      // 获取输入内容
      let receiveUserIdEl = $('#index_message_receive_user_id');
      let messageContentEl = $('#index_message_receive_content');
      // 校验
      if (!receiveUserIdEl.val()) {
        $.toast({
            heading: '警告',
            text: '出错了，请联系管理员',
            icon: 'warning'
          });
          return;
      }
      if (!messageContentEl.val()) {
        $.toast({
          heading: '警告',
          text: '请输入要发送的内容',
          icon: 'warning'
        });
        // 输入框
        messageContentEl.focus();
        retrun;
      }

      // 构造发送数据
      let postData = {
        receiveUserId : receiveUserIdEl.val(),
        content : messageContentEl.val()
      };

      // 发送站内信请求 url = message/send, 成功与失败都调用cleanMessageForm()方法，清空输入框
      $.ajax({
        type: 'POST',
        url: 'message/send',
        contentType: 'application/x-www-form-urlencoded',
        data: postData,
        success: function(response) {
        if (response.code == 0) {
            // 提示信息
            $.toast({
              heading: '成功',
              text: '发送成功',
              icon: 'success'
            });
            // 清空输入框
            cleanMessageForm();
        } else {
            // 提示信息
            $.toast({
              heading: '警告',
              text: response.message,
              icon: 'warning'
            });
        }
      },
      error: function() {
          // 提示信息
          $.toast({
            heading: '错误',
            text: '访问出现问题',
            icon: 'error'
        });
      }
      });
    });

    // 清空站内信输入区
    function cleanMessageForm () {
      $('#index_message_receive_user_id').val('');
      $('#index_message_receive_user_name').html('');
      $('#index_message_receive_content').val('');
    }
    // ============ 站内信取消接钮事件 ============
    $('#index_message_receive_cancel').click(function () {
      // 清空
      cleanMessageForm();
    });

    // ============ 获取用户未读站内信数量 ============
    // url = message/getUnreadCount
    // 成功后，处理小红点是否显示 #index_nva_message_badge
    function requestMessageUnreadCount() {
      $.ajax({
        type: 'GET',
        url: 'message/getUnreadCount',
        success: function(response) {
          if (response.code == 0) {
            let messageBadgeEl = $('#index_nva_message_badge');
            // 更新未读消息数量
            if (response.data <= 0) {
              messageBadgeEl.fadeOut(300);  // 使用淡出动画
              messageBadgeEl.data('count', 0);
              return;
            }
            
            // 显示未读消息数量
            messageBadgeEl.text(response.data);
            // 使用淡入动画显示
            if (!messageBadgeEl.is(':visible')) {
              messageBadgeEl.fadeIn(300);
            }
            
            // 如果数量发生变化,添加动画效果
            let oldCount = parseInt(messageBadgeEl.data('count') || 0);
            if (response.data !== oldCount) {
              messageBadgeEl.addClass('new-message');
              // 同时触发铃铛动画
              messageBadgeEl.closest('.nav-link').find('.icon').css('animation', 'bellRing 0.8s ease-in-out');
              setTimeout(() => {
                messageBadgeEl.removeClass('new-message');
                messageBadgeEl.closest('.nav-link').find('.icon').css('animation', '');
              }, 1000);
            }
            messageBadgeEl.data('count', response.data);
          } else {
            $.toast({
              heading: '警告',
              text: response.message,
              icon: 'warning'
            });
          }
        },
        error: function() {
          $.toast({
            heading: '错误',
            text: '访问出现问题，请与管理员联系.',
            icon: 'error'
          });
        }
      });
    }
    requestMessageUnreadCount();
    
    // 添加定时轮询未读消息
    setInterval(requestMessageUnreadCount, 30000); // 每30秒检查一次新消息

    // ============ 获取用户所有站内信 ============
    // 成功后，调用buildMessageList() 方法构建站内信列表
    function requestMessageList () {
      $.ajax({
        type: 'GET',
        url: 'message/getAll',
        success: function(response) {
        if (response.code == 0) {
          // 构建站内信列表
          buildMessageList(response.data);
        } else {
            // 提示信息
            $.toast({
              heading: '警告',
              text: response.message,
              icon: 'warning'
            });
        }
      },
      error: function() {
          // 提示信息
          $.toast({
            heading: '错误',
            text: '访问出现问题',
            icon: 'error'
        });
      }
      });
    }
    requestMessageList();
    

    // ============ 处理站内信列表页面 ============
    function buildMessageList(messageList) {
      // 获取父标签
      let messageDivEl = $('#index_div_message');
      if (!messageList || messageList.length == 0) {
        messageDivEl.html('<strong>没有站内信</strong>');
        return;
      }
      // 获取站内信列表父标签
      let messageListDivEl = $('#index_div_message_list');
      messageListDivEl.html('');
      // 遍历结果
      messageList.forEach(messageItem => {
        let itemHtml = ' <div class="list-group-item"> '
          + ' <div class="row align-items-center"> '
          + ' <div class="col-auto"><span class="status-dot d-block"></span></div> '
          + ' <div class="col text-truncate"> '
          + ' <a href="javascript:void(0);" class="text-body d-block index_message_title" data-bs-toggle="modal" data-bs-target="#index_message_reply_modal"> '
          +  ' <span class="index_message_item_statue">[已读]</span> &nbsp; '
          + ' <span>来自 <strong> '+ messageItem.postUser.nickname 
          + ' </strong> 的消息</span></a> '
          + ' <div class="d-block text-muted text-truncate mt-n1"> '
          + messageItem.content
          + ' </div> '
          + ' </div> '
          + ' <div class="col-auto"> '
          + ' <a href="javascript:void(0);" class="list-group-item-actions" data-bs-toggle="modal" data-bs-target="#index_message_reply_modal"> '
          + ' <svg xmlns="http://www.w3.org/2000/svg" class="icon text-muted bi bi-reply" width="24" height="24" '
          + ' fill="currentColor" viewBox="0 0 16 16"> '
          + ' <path d="M6.598 5.013a.144.144 0 0 1 .202.134V6.3a.5.5 0 0 0 .5.5c.667 0 2.013.005 3.3.822.984.624 1.99 1.76 2.595 3.876-1.02-.983-2.185-1.516-3.205-1.799a8.74 8.74 0 0 0-1.921-.306 7.404 7.404 0 0 0-.798.008h-.013l-.005.001h-.001L7.3 9.9l-.05-.498a.5.5 0 0 0-.45.498v1.153c0 .108-.11.176-.202.134L2.614 8.254a.503.503 0 0 0-.042-.028.147.147 0 0 1 0-.252.499.499 0 0 0 .042-.028l3.984-2.933zM7.8 10.386c.068 0 .143.003.223.006.434.02 1.034.086 1.7.271 1.326.368 2.896 1.202 3.94 3.08a.5.5 0 0 0 .933-.305c-.464-3.71-1.886-5.662-3.46-6.66-1.245-.79-2.527-.942-3.336-.971v-.66a1.144 1.144 0 0 0-1.767-.96l-3.994 2.94a1.147 1.147 0 0 0 0 1.946l3.994 2.94a1.144 1.144 0 0 0 1.767-.96v-.667z"/> '
          + ' </svg> '
          + ' </a> '
          + ' </div> '
          + ' </div> '
          + ' </div>';
        
        // 转为jQuery对象
        let messageItemEL = $(itemHtml);
        // 设置状态 bg-green bg-red status-dot-animated
        let statusDotEl = messageItemEL.find('.status-dot');
        let statusDescEl = messageItemEL.find('.index_message_item_statue');
        if (messageItem.state == 0) {
          // 未读
          statusDotEl.addClass('status-dot-animated bg-red');
          statusDescEl.html('[未读]');
        } else if (messageItem.state == 1) {
          // 已读
          statusDescEl.html('[已读]');
        } else if (messageItem.state == 2) {
          // 已回复
          statusDotEl.addClass('bg-green');
          statusDescEl.html('[已回复]');
        }
        // 绑定数据
        messageItemEL.data('message', messageItem);
        // 绑定点击事件
        messageItemEL.find('.list-group-item-actions, .index_message_title').click(function () {
          // 详情与回复页面数据
          // 站内信Id
          $('#index_message_detail_id').val(messageItem.id);
          // 标题
          $('#index_message_detail_title').html('收到来自 <strong>' + messageItem.postUser.nickname + '</strong> 的新消息');
          // 内容
          $('#index_message_detail_content').html(messageItem.content);
          // 接收者Id
          $('#index_message_reply_receive_user_id').val(messageItem.postUser.id);
          // 接收者信息
          $('#index_message_reply_receive_user_name').html('回复给: ' + messageItem.postUser.nickname);
          // 复位回复区域
          $('#index_message_reply_div').hide();
          // 复位接钮显示 
          $('#btn_index_message_reply').show();
          $('#btn_index_send_message_reply').hide();

          // 发送请求，更新状态为已读
          if (messageItem.state == 0 && statusDotEl.hasClass('status-dot-animated bg-red')) {
            $.ajax ({
              type : 'post',
              url : 'message/markRead',
              contentType : 'application/x-www-form-urlencoded',
              data : {id : messageItem.id},
              // 成功回调
              success : function (respData) {
              if (respData.code == 0) {
                // 更新⻚⾯显⽰效果和messageItem.state
                statusDotEl.removeClass('status-dot-animated bg-red');
                // 修改未读为已读
                statusDescEl.html('[已读]');
                // 修改本地的对象状态属性
                messageItem.state = 1;
                }
              }
            });
          }

        });

        // 添加到列表
        messageListDivEl.append(messageItemEL);

      });
    }
    
    // ============ 处理阅读和回复站内信 ============
    // 清空站内信输入区
    function cleanMessageReplyForm () {
      // 详情区
      $('#index_message_detail_id').val('');
      $('#index_message_detail_title').html('');
      $('#index_message_detail_content').html('');
      // 回复区
      $('#index_message_reply_receive_user_id').val('');
      $('#index_message_reply_receive_user_name').html('');
      $('#index_message_reply_receive_content').val('');
      console.log(123);
    }
    // ============ 站内信取消接钮事件 ============
    $('#index_message_reply_cancel').click(function () {
      // 清空
      cleanMessageReplyForm();
    });

    // 处理回复站内信按钮事件
    $('#btn_index_message_reply').click(function () {
      // 清空内容区
      $('#index_message_reply_receive_content').val('');
      // 显示回复区域
      $('#index_message_reply_div').show();
      // 隐藏回复按钮，显示发送按钮
      $(this).hide();
      $('#btn_index_send_message_reply').show();
    });

    // ============ 绑定发送按钮事件 ============
    $('#btn_index_send_message_reply').click(function () {
      // 校验用户输入
      let replyReceiveContentEl = $('#index_message_reply_receive_content');
      if (!replyReceiveContentEl.val()) {
        $.toast({
          heading: '警告',
          text: '请输入要回复的内容',
          icon: 'warning'
        });
        // 输入框
        replyReceiveContentEl.focus();
        retrun;
      }

      // 构造请求数据
      let postData = {
        repliedId: $('#index_message_detail_id').val(),
        receiveUserId : $('#index_message_reply_receive_user_id').val(),
        content: replyReceiveContentEl.val()
      };

      // 发送请求 message/reply
      // 回复成功后刷新未读标识和站内信列表
      // requestMessageUnreadCount();
      // requestMessageList();
      // // 清空输入区
      // cleanMessageReplyForm ();
      $.ajax ({
        type : 'post',
        url : 'message/reply',
        contentType : 'application/x-www-form-urlencoded',
        data : postData,
          // 回调
          success : function (respData) {
          if (respData.code == 0) {
            // 回复成功后刷新未读标识和站内信列表
            requestMessageUnreadCount();
            requestMessageList();
            // 清空输⼊区
            cleanMessageReplyForm ();
            // 提⽰信息
            $.toast({
              heading: '成功',
              text: '发送成功',
              icon: 'success'
            });
          } else {
              // 提⽰信息
              $.toast({
              heading: '警告',
              text: respData.message,
              icon: 'warning'
            });
          }
          },
          error : function () {
              // 提⽰信息
              $.toast({
              heading: '错误',
              text: '访问出现问题，请与管理员联系.',
              icon: 'error'
              });
          }
      });

    });

    // 优化搜索框交互
    $(function() {
      // 清空按钮显示/隐藏
      $('#searchKeyword').on('input', function() {
        const clearIcon = $(this).siblings('.clear-icon');
        if ($(this).val().trim()) {
          clearIcon.fadeIn(200);
        } else {
          clearIcon.fadeOut(200);
        }
      });

      // 清空按钮点击事件
      $('.clear-icon').click(function() {
        $('#searchKeyword').val('').focus();
        $(this).fadeOut(200);
        // 触发搜索
        $('#searchKeyword').trigger('input');
      });

      // 搜索框焦点效果
      $('#searchKeyword').on('focus', function() {
        $(this).closest('.search-container').addClass('focused');
      }).on('blur', function() {
        $(this).closest('.search-container').removeClass('focused');
      });

      // 优化搜索请求
      let searchTimer;
      let lastSearchTime = 0;
      const SEARCH_DEBOUNCE = 300; // 防抖时间

      $('#searchKeyword').on('input', function() {
        const now = Date.now();
        if (now - lastSearchTime < SEARCH_DEBOUNCE) {
          clearTimeout(searchTimer);
        }
        lastSearchTime = now;

        searchTimer = setTimeout(() => {
          const keyword = $(this).val().trim();
          const boardId = $('#searchBoardId').val() || null;

          if (!keyword && !boardId) {
            buildArticleList();
            return;
          }

          // 显示加载动画
          $('#bit-forum-content').html('<div class="d-flex justify-content-center p-5"><div class="spinner-border text-primary" role="status"></div></div>');

          $.ajax({
            type: 'GET',
            url: '/article/search',
            data: { keyword, boardId },
            success: function(response) {
              if (response.code == 0) {
                if (response.data.length === 0) {
                  $('#bit-forum-content').html('<div class="container-xl"><div class="alert alert-info">未找到相关帖子</div></div>');
                  return;
                }

                // 构建搜索结果页面
                let html = '<div class="container-xl">';
                html += '<div class="page-header d-print-none">';
                html += '<div class="container-xl">';
                html += '<div class="row g-2 align-items-center">';
                html += '<div class="col">';
                html += '<h2 class="page-title">搜索结果</h2>';
                html += '<div class="text-muted mt-1">找到 ' + response.data.length + ' 条结果</div>';
                html += '</div></div></div></div>';

                html += '<div class="row justify-content-center">';
                html += '<div class="col-12">';
                html += '<div class="card">';
                html += '<div class="card-body">';
                html += '<div class="divide-y" id="search-result-body">';

                // 遍历结果构建帖子列表
                response.data.forEach(function(article) {
                  const avatarUrl = article.user.avatarUrl || 'image/avatar01.jpeg';
                  
                  // 高亮搜索关键词
                  let highlightedTitle = article.title;
                  if (keyword) {
                    const regex = new RegExp(keyword, 'gi');
                    highlightedTitle = highlightedTitle.replace(regex, match => 
                      `<span class="search-result-highlight">${match}</span>`
                    );
                  }

                  html += `<div class="search-result-item">
                    <div class="row">
                      <div class="col-auto">
                        <span class="avatar" style="background-image: url(${avatarUrl})"></span>
                      </div>
                      <div class="col">
                        <div class="search-result-title">
                          <a href="javascript:void(0);" class="article_list_a_title">
                            ${highlightedTitle}
                          </a>
                        </div>
                        <div class="search-result-meta">
                          <div class="row">
                            <div class="col">
                              <ul class="list-inline list-inline-dots mb-0">
                                <li class="list-inline-item">
                                  <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-user" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
                                    <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
                                    <path d="M12 7m-4 0a4 4 0 1 0 8 0a4 4 0 1 0 -8 0"></path>
                                    <path d="M6 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2"></path>
                                  </svg>
                                  ${article.user.nickname}
                                </li>
                                <li class="list-inline-item">
                                  <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-clock-edit" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
                                    <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
                                    <path d="M21 12a9 9 0 1 0 -9.972 8.948c.32 .034 .644 .052 .972 .052"></path>
                                    <path d="M12 7v5l2 2"></path>
                                    <path d="M18.42 15.61a2.1 2.1 0 0 1 2.97 2.97l-3.39 3.42h-3v-3l3.42 -3.39z"></path>
                                  </svg>
                                  ${new Date(article.createTime).toLocaleString()}
                                </li>
                              </ul>
                            </div>
                            <div class="col-auto d-none d-md-inline">
                              <ul class="list-inline list-inline-dots mb-0">
                                <li class="list-inline-item">
                                  <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-eye" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
                                    <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
                                    <path d="M12 12m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0"></path>
                                    <path d="M22 12c-2.667 4.667 -6 7 -10 7s-7.333 -2.333 -10 -7c2.667 -4.667 6 -7 10 -7s7.333 2.333 10 7"></path>
                                  </svg>
                                  ${article.visitCount}
                                </li>
                                <li class="list-inline-item">
                                  <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-heart" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
                                    <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
                                    <path d="M19.5 12.572l-7.5 7.428l-7.5 -7.428a5 5 0 1 1 7.5 -6.566a5 5 0 1 1 7.5 6.572"></path>
                                  </svg>
                                  ${article.likeCount}
                                </li>
                                <li class="list-inline-item">
                                  <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-message-circle" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
                                    <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
                                    <path d="M3 20l1.3 -3.9a9 8 0 1 1 3.4 2.9l-4.7 1"></path>
                                    <path d="M12 12l0 .01"></path>
                                    <path d="M8 12l0 .01"></path>
                                    <path d="M16 12l0 .01"></path>
                                  </svg>
                                  ${article.replyCount}
                                </li>
                              </ul>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>`;
                });

                html += '</div></div></div></div></div>';
                $('#bit-forum-content').html(html);

                // 绑定点击事件
                $('.article_list_a_title').click(function() {
                  const article = response.data[$(this).closest('.search-result-item').index()];
                  currentArticle = article;
                  removeNavActive();
                  $('#bit-forum-content').load('details.html');
                });

              } else {
                $.toast({
                  heading: '警告',
                  text: response.message,
                  icon: 'warning'
                });
              }
            },
            error: function() {
              $.toast({
                heading: '错误',
                text: '搜索请求失败，请稍后重试',
                icon: 'error'
              });
            }
          });
        }, SEARCH_DEBOUNCE);
      });

      // 板块选择变化事件
      $('#searchBoardId').on('change', function() {
        if (!$(this).val() && !$('#searchKeyword').val().trim()) {
          buildArticleList();
          return;
        }
        $('#searchKeyword').trigger('input');
      });
    });
  });

  // 页面加载动画
  $(window).on('load', function() {
    $('#pageLoading').fadeOut();
  });

  // 返回顶部按钮
  $(window).scroll(function() {
    if ($(this).scrollTop() > 300) {
      $('#scrollToTop').fadeIn();
    } else {
      $('#scrollToTop').fadeOut();
    }
  });

  $('#scrollToTop').click(function() {
    $('html, body').animate({scrollTop: 0}, 500);
    return false;
  });

  // 优化站内信动画
  $('#index_message_offcanvasEnd').on('show.bs.offcanvas', function() {
    $(this).find('.list-group-item').each(function(i) {
      $(this).css('animation-delay', (i * 0.1) + 's');
    });
  });

  // 添加页面切换动画
  function loadContent(url) {
    $('#bit-forum-content').fadeOut(200, function() {
      $(this).load(url, function() {
        $(this).fadeIn(200);
      });
    });
  }

  // 优化模态框动画
  $('.modal').on('show.bs.modal', function() {
    $(this).find('.modal-dialog').css('transform', 'scale(0.8)');
    setTimeout(() => {
      $(this).find('.modal-dialog').css('transform', 'scale(1)');
    }, 50);
  });

  // AI对话功能
  $(function() {
    const chatMessages = $('#chatMessages');
    const chatInput = $('#chatInput');
    const chatSendBtn = $('#chatSendBtn');
    let isTyping = false;

    // 滚动到聊天底部
    function scrollToBottom() {
      chatMessages.scrollTop(chatMessages[0].scrollHeight);
    }

    // 添加消息到聊天界面
    function addMessage(content, isUser = false) {
      const messageClass = isUser ? 'user' : 'ai';
      const avatar = isUser ? '我' : 'AI';
      
      const messageHtml = `
        <div class="chat-message ${messageClass}">
          <div class="message-avatar">${avatar}</div>
          <div class="message-content">${content}</div>
        </div>
      `;
      
      chatMessages.append(messageHtml);
      scrollToBottom();
    }

    // 显示打字指示器
    function showTypingIndicator() {
      if (isTyping) return;
      isTyping = true;
      
      const typingHtml = `
        <div class="chat-message ai typing-message">
          <div class="message-avatar">AI</div>
          <div class="message-content">
            <div class="typing-indicator">
              <div class="typing-dot"></div>
              <div class="typing-dot"></div>
              <div class="typing-dot"></div>
            </div>
          </div>
        </div>
      `;
      
      chatMessages.append(typingHtml);
      scrollToBottom();
    }

    // 隐藏打字指示器
    function hideTypingIndicator() {
      $('.typing-message').remove();
      isTyping = false;
    }

    // 生成会话ID
    function generateMemoryId() {
      return 'chat_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
    }
    
    let memoryId = generateMemoryId();

    // 发送消息到后端
    function sendMessageToAI(message) {
      showTypingIndicator();
      chatSendBtn.prop('disabled', true);
      
      // 调用后端AI流式接口
      const url = `/ai/chat?memoryId=${encodeURIComponent(memoryId)}&message=${encodeURIComponent(message)}`;
      
      fetch(url, {
        method: 'GET',
        headers: {
          'Accept': 'text/event-stream'
        }
      })
      .then(response => {
        hideTypingIndicator();
        
        if (!response.ok) {
          throw new Error('Network response was not ok');
        }
        
        // 处理流式响应
        const reader = response.body.getReader();
        // 明确指定UTF-8解码器，并设置错误处理
        const decoder = new TextDecoder('utf-8', { fatal: false, ignoreBOM: true });
        let aiResponse = '';
        
        // 添加AI消息容器
        const messageId = 'ai-msg-' + Date.now();
        const messageHtml = `
          <div class="chat-message ai" id="${messageId}">
            <div class="message-avatar">AI</div>
            <div class="message-content"></div>
          </div>
        `;
        chatMessages.append(messageHtml);
        const messageContent = $(`#${messageId} .message-content`);
        
        function readStream() {
          reader.read().then(({ done, value }) => {
            if (done) {
              chatSendBtn.prop('disabled', false);
              return;
            }
            
            const chunk = decoder.decode(value, { stream: true });
            
            // 解析SSE格式数据
            const lines = chunk.split('\n');
            for (const line of lines) {
              if (line.startsWith('data:')) {
                const data = line.substring(5).trim();
                if (data && data !== '[DONE]') {
                  // 直接使用接收到的数据，不进行额外处理
                  aiResponse += data;
                }
              }
            }
            
            // 使用text()方法避免HTML转义问题，确保中文正确显示
            messageContent.text(aiResponse);
            // 手动处理换行符
            const formattedText = aiResponse.replace(/\n/g, '\n');
            messageContent.text(formattedText);
            scrollToBottom();
            
            readStream();
          }).catch(error => {
            console.error('Stream reading error:', error);
            chatSendBtn.prop('disabled', false);
          });
        }
        
        readStream();
      })
      .catch(error => {
        hideTypingIndicator();
        console.error('AI请求失败:', error);
        
        // 模拟AI回复（当后端接口不可用时）
        setTimeout(() => {
          const responses = [
            '感谢您的提问！作为论坛的AI助手，我可以帮助您解答技术问题。',
            '这是一个很好的问题！您可以在相关板块发帖讨论，会有更多专业人士为您解答。',
            '建议您查看论坛的技术文档或搜索相关帖子，可能会找到您需要的答案。',
            '如果您遇到技术难题，可以详细描述问题现象，我会尽力为您提供解决思路。'
          ];
          const randomResponse = responses[Math.floor(Math.random() * responses.length)];
          addMessage(randomResponse);
        }, 1000);
        
        chatSendBtn.prop('disabled', false);
      });
    }

    // 发送消息
    function sendMessage() {
      const message = chatInput.val().trim();
      if (!message) return;
      
      // 添加用户消息
      addMessage(message, true);
      chatInput.val('');
      
      // 发送到AI
      sendMessageToAI(message);
    }

    // 新建对话功能
    function startNewChat() {
      // 生成新的会话ID
      memoryId = generateMemoryId();
      
      // 清空聊天记录，只保留欢迎消息
      chatMessages.empty();
      const welcomeMessage = `
        <div class="chat-message ai">
          <div class="message-avatar">AI</div>
          <div class="message-content">
            你好！我是论坛的AI智能助手，可以帮助你解答技术问题、提供学习建议或协助你更好地使用论坛功能。有什么我可以帮助你的吗？
          </div>
        </div>
      `;
      chatMessages.append(welcomeMessage);
      
      // 清空输入框
      chatInput.val('');
      chatInput.css('height', 'auto');
      
      // 滚动到底部
      scrollToBottom();
      
      // 聚焦输入框
      chatInput.focus();
    }

    // 绑定新建对话按钮点击事件
    $('#newChatBtn').click(startNewChat);

    // 绑定发送按钮点击事件
    chatSendBtn.click(sendMessage);

    // 绑定回车键发送
    chatInput.keypress(function(e) {
      if (e.which === 13 && !e.shiftKey) {
        e.preventDefault();
        sendMessage();
      }
    });

    // 自动调整输入框高度
    chatInput.on('input', function() {
      this.style.height = 'auto';
      this.style.height = Math.min(this.scrollHeight, 100) + 'px';
    });

    // 模态框显示时聚焦输入框
    $('#aiChatModal').on('shown.bs.modal', function() {
      chatInput.focus();
      scrollToBottom();
    });

    // 模态框关闭时清理
    $('#aiChatModal').on('hidden.bs.modal', function() {
      chatInput.val('');
      chatInput.css('height', 'auto');
    });
  });
</script>

</html>